﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Yxinmt.SmarterStreaming
{
    public class StreamingMediaManager
    {
        public static SmartPlayer _SmartPlayer { get; set; }
        public static SmartPublisher _SmartPublisher { get; set; }
        public static bool IsRECRecord { get; set; }
        public static bool IsPublisher { get; set; }
        public static bool IsPlay { get; set; }

        public static SmartPublisherConfig SmartPublisherConfig { get; set; }
        public static SmartPlayerConfig SmartPlayerConfig { get; set; }

        public static void InitConfig()
        {
            if (SmartPlayerConfig == null)
            {
                SmartPlayerConfig = new SmartPlayerConfig();
                SmartPlayerConfig.BufferTime = 100;
                SmartPlayerConfig.IsFastStartup = true;
                SmartPlayerConfig.IsMute = true;

                SmartPlayerConfig.LocalRecorder.IsAppendDate = true;
                SmartPlayerConfig.LocalRecorder.IsAppendTime = true;
                SmartPlayerConfig.LocalRecorder.SingleRecordMaxFileSize = 200;
            }
            else
            {
                SmartPlayerConfig.LocalRecorder.IsAppendDate = true;
                SmartPlayerConfig.LocalRecorder.IsAppendTime = true;
                if (SmartPlayerConfig.LocalRecorder.SingleRecordMaxFileSize == 0) SmartPlayerConfig.LocalRecorder.SingleRecordMaxFileSize = 200;
            }

            if (SmartPublisherConfig == null)
            {
                SmartPublisherConfig = new SmartPublisherConfig();

                SmartPublisherConfig.AudioCollectionSetting.EchoDelay = 100;
                SmartPublisherConfig.AudioCollectionSetting.IsAuidoMicInput = true;
                SmartPublisherConfig.AudioCollectionSetting.IsEchoCancel = true;
                SmartPublisherConfig.AudioCollectionSetting.IsNoiseSuppression = true;
                SmartPublisherConfig.AudioCollectionSetting.IsSpeexEncoder = true;
                SmartPublisherConfig.AudioCollectionSetting.SpeexQuality = 8;

                SmartPublisherConfig.LocalRecorder.IsAppendDate = true;
                SmartPublisherConfig.LocalRecorder.IsAppendTime = true;
                SmartPublisherConfig.LocalRecorder.SingleRecordMaxFileSize = 200;

                SmartPublisherConfig.VideoCollectionSetting = new VideoCollectionSetting();
                SmartPublisherConfig.VideoCollectionSetting.CaptureFps = 5;
                SmartPublisherConfig.VideoCollectionSetting.IsDesktopInput = true;

                SmartPublisherConfig.VideoRateControl.AvgBitRate = 560;
                SmartPublisherConfig.VideoRateControl.H264Profile = EnumH264ProfileType.Baseline;
                SmartPublisherConfig.VideoRateControl.IsVideoBitRate = true;
                SmartPublisherConfig.VideoRateControl.KeyFrame = 15;
                SmartPublisherConfig.VideoRateControl.VideoEncodeSpeed = 3;
                SmartPublisherConfig.VideoRateControl.VideoMaxBitRate = 1100;
                SmartPublisherConfig.VideoRateControl.VideoQuality = 10;
            }
            else
            {
                SmartPublisherConfig.VideoCollectionSetting.IsDesktopInput = true;
                SmartPublisherConfig.LocalRecorder.IsAppendDate = true;
                SmartPublisherConfig.LocalRecorder.IsAppendTime = true;
            }

            _SmartPlayerDictionary = new Dictionary<long, SmartPlayer>();
        }

        /// <summary>
        /// 开始推送
        /// </summary>
        /// <param name="window"></param>
        /// <param name="publishUrl"></param>
        public static void StartPublish(System.Windows.Window window, string publishUrl)
        {
            if (_SmartPublisher != null && IsPublisher) return;

            try
            {
                SmartPublisherConfig.RtmpPublisher.PublishUrl = publishUrl;

                SmartPublisherConfig.VideoCollectionSetting.ScreenClip.Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                SmartPublisherConfig.VideoCollectionSetting.ScreenClip.Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;

                if (_SmartPublisher == null) _SmartPublisher = new SmartPublisher(window, SmartPublisherConfig);
                _SmartPublisher.StartPublish(publishUrl);

                IsPublisher = true;
            }
            catch (Exception ex)
            {
                StopPublish();
                //AlertException("StreamingMediaManager", "StartPublish", ex);
                throw ex;
            }
        }

        /// <summary>
        /// 停止推送
        /// </summary>
        public static void StopPublish()
        {
            if (_SmartPublisher != null)
            {
                _SmartPublisher.StopPublish();
                IsPublisher = false;

                if (!IsPublisher && !IsRECRecord) _SmartPublisher = null;
            }
        }

        /// <summary>
        /// 开始播放
        /// </summary>
        /// <param name="window"></param>
        /// <param name="pictureBox"></param>
        /// <param name="playUrl"></param>
        public static SmartPlayer StartPlay(System.Windows.Window window, System.Windows.Controls.Image image, string playUrl, Action<string> setStatus)
        {
            if (_SmartPlayer != null) return _SmartPlayer;

            try
            {
                SmartPlayerConfig.PlayUrl = playUrl;
                _SmartPlayer = new SmartPlayer(window, image, SmartPlayerConfig, setStatus);
                _SmartPlayer.Play();

                IsPlay = true;
            }
            catch (Exception ex)
            {
                StopPlay();
                //AlertException("StreamingMediaManager", "StartPlay", ex);
                throw ex;
            }

            return _SmartPlayer;
        }

        public static SmartPlayer StartPlay(System.Windows.Window window, System.Windows.Forms.PictureBox pictureBox, string playUrl, Action<string> setStatus)
        {
            SmartPlayerConfig.PlayUrl = playUrl;
            var player = new SmartPlayer(window, pictureBox, SmartPlayerConfig, setStatus);
            player.Play();

            return player;
        }

        public static void StopPlay()
        {
            if (_SmartPlayer != null)
            {
                _SmartPlayer.Stop();
                _SmartPlayer = null;
                IsPlay = false;
                Thread.Sleep(300);
            }
        }

        public static void StopPlay(SmartPlayer player)
        {
            if (player != null)
            {
                player.Stop();
                player = null;
                Thread.Sleep(300);
            }
        }

        public static Func<System.Windows.Window> GetCurrectWindow { get; set; }

        public static Action<string, string, Exception> AlertException { get; set; }

        public static void StartRecord(long meetingId, string recordDirName, string fileName)
        {
            System.Windows.Window win = GetCurrectWindow();

            if (_SmartPublisher != null && IsRECRecord) return;

            Task.Run(() =>
            {
                StartRECRecord(win, meetingId, recordDirName, fileName);
            });
        }

        static void StartRECRecord(System.Windows.Window window, long meetingId, string recordDirName, string fileName)
        {
            try
            {
                SmartPublisherConfig.VideoCollectionSetting.ScreenClip.Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                SmartPublisherConfig.VideoCollectionSetting.ScreenClip.Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;

                SmartPublisherConfig.LocalRecorder.RecordDir = AppDomain.CurrentDomain.BaseDirectory + string.Format("MeetingRECRecord\\{0}", recordDirName);
                SmartPublisherConfig.LocalRecorder.FileNamePrefix = fileName;

                if (!System.IO.Directory.Exists(SmartPublisherConfig.LocalRecorder.RecordDir)) System.IO.Directory.CreateDirectory(SmartPublisherConfig.LocalRecorder.RecordDir);

                if (_SmartPublisher == null) _SmartPublisher = new SmartPublisher(window, SmartPublisherConfig);
                _SmartPublisher.StartRecord(SmartPublisherConfig.LocalRecorder.RecordDir, SmartPublisherConfig.LocalRecorder.FileNamePrefix);

                IsRECRecord = true;
            }
            catch (Exception ex)
            {
                StopRecord();
                AlertException("StreamingMediaManager", "StartRECRecord", ex);
            }
        }

        public static void StartDirectVideoRecord(long meetingId, string recordDirName, string fileName, long videoId, string videoUrl)
        {
            System.Windows.Window win = GetCurrectWindow();

            if (_SmartPlayerDictionary.ContainsKey(videoId)) return;

            Task.Run(() =>
            {
                StartDirectRECRecord(win, meetingId, recordDirName, fileName, videoId, videoUrl);
            });
        }

        static void StartDirectRECRecord(System.Windows.Window window, long meetingId, string recordDirName, string fileName, long videoId, string videoUrl)
        {
            try
            {
                SmartPlayerConfig.LocalRecorder.RecordDir = AppDomain.CurrentDomain.BaseDirectory + string.Format("MeetingRECRecord\\{0}", recordDirName);
                SmartPlayerConfig.LocalRecorder.FileNamePrefix = fileName;

                if (!System.IO.Directory.Exists(SmartPlayerConfig.LocalRecorder.RecordDir)) System.IO.Directory.CreateDirectory(SmartPlayerConfig.LocalRecorder.RecordDir);

                SmartPlayer player = null;
                if (_SmartPlayerDictionary.ContainsKey(videoId)) player = _SmartPlayerDictionary[videoId];

                if (player == null)
                {
                    player = new SmartPlayer(window, SmartPlayerConfig);
                    _SmartPlayerDictionary[videoId] = player;
                }
                player.StartRecord(SmartPlayerConfig.LocalRecorder.RecordDir, SmartPlayerConfig.LocalRecorder.FileNamePrefix, videoUrl);
            }
            catch (Exception ex)
            {
                StopDirectRECRecord(videoId);
                AlertException("StreamingMediaManager", "StartDirectRECRecord", ex);
            }
        }

        static Dictionary<long, SmartPlayer> _SmartPlayerDictionary { get; set; }

        public static void StopDirectRECRecord(long videoId)
        {
            SmartPlayer player = null;
            if (_SmartPlayerDictionary.ContainsKey(videoId)) player = _SmartPlayerDictionary[videoId];
            if (player != null)
            {
                player.StopRecord();
                _SmartPlayerDictionary.Remove(videoId);
                player = null;
            }

            Thread.Sleep(300);
        }

        public static void StopRecord()
        {
            if (_SmartPublisher != null)
            {
                _SmartPublisher.StopRecord();
                IsRECRecord = false;
                if (!IsPublisher && !IsRECRecord) _SmartPublisher = null;
            }

            Thread.Sleep(300);
        }

        /// <summary>
        /// 获取录制文件路径列表
        /// </summary>
        /// <returns></returns>
        public static List<string> GetRecordFilePathList(string recordDirName)
        {
            Thread.Sleep(1000);

            string dir = AppDomain.CurrentDomain.BaseDirectory + string.Format("MeetingRECRecord\\{0}", recordDirName);

            if (!System.IO.Directory.Exists(dir)) return new List<string>();

            return System.IO.Directory.GetFiles(dir).ToList();
        }
    }
}
